#! /usr/bin/env python

import os
import subprocess

class WorkerError(Exception):
    """Base class for all exceptions raised by this module.
    """
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)

class Worker:
    def __init__(self, program, stderr = '/dev/null'):
        self.program    = program
        self.stderr     = stderr
        self.pid        = None

    def run(self):
        PIPE = subprocess.PIPE
        self.child = subprocess.Popen([self.program,], stdin = PIPE, stdout = PIPE, \
            stderr = open(self.stderr, 'w'), close_fds = True, cwd = '/')
        self.outfd = self.child.stdout.fileno()
        self.pid = self.child.pid

    def response(self):
        response_line   = self.child.stdout.readline()
        if response_line != 'RESPONSE TP/1.0\r\n':
            raise WorkerError('Invalid response line')

        id_line         = self.child.stdout.readline()
        id = int(id_line.strip().split(': ')[1])

        length_line     = self.child.stdout.readline()
        length = int(length_line.strip().split(': ')[1])
        
        CRLF = self.child.stdout.readline()
        if CRLF != '\r\n':
            raise WorkerError('Invalid header ends')

        task = self.child.stdout.read(length)

        return id, task

    def request(self, id, task):
        request_line    = 'REQUEST TP/1.0\r\n'
        id_line         = 'ID: %d\r\n' % id
        length_line     = 'Length: %d\r\n' % len(task)
        header = request_line + id_line + length_line + '\r\n'
        self.child.stdin.write(header + task)

    def quit(self):
        self.child.kill()
        return self.child.wait()

if __name__ == '__main__':
    worker = Worker('/root/worker/worker_demo.sh')
    try:
        worker.run()
        for i in range(10):
            worker.request(i, 'task: %d' % i)
            id, result = worker.response()
            print id
            print result
            print '=' * 32
    finally:
        worker.quit()
